package cn.hamster3.mc.plugin.ball.bungee;

import cn.hamster3.mc.plugin.ball.bungee.api.BallBungeeCordAPI;
import cn.hamster3.mc.plugin.ball.bungee.listener.BallBungeeListener;
import cn.hamster3.mc.plugin.ball.bungee.listener.BallBungeeMainListener;
import cn.hamster3.mc.plugin.ball.bungee.listener.UpdatePlayerInfoListener;
import cn.hamster3.mc.plugin.ball.bungee.util.BallBungeeCordUtils;
import cn.hamster3.mc.plugin.ball.common.api.BallAPI;
import cn.hamster3.mc.plugin.ball.common.entity.BallPlayerInfo;
import cn.hamster3.mc.plugin.ball.common.event.BallActions;
import cn.hamster3.mc.plugin.ball.common.event.server.ServerOnlineEvent;
import lombok.Getter;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Plugin;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.logging.Level;
import java.util.logging.Logger;

public class HamsterBallPlugin extends Plugin {
    @Getter
    private static HamsterBallPlugin instance;

    @Override
    public void onLoad() {
        long start = System.currentTimeMillis();
        Logger logger = getLogger();
        logger.info("仓鼠球正在初始化");
        instance = this;
        try {
            File dataFolder = getDataFolder();
            if (dataFolder.mkdir()) {
                logger.info("已生成插件存档文件夹");
            }
            File configFile = new File(dataFolder, "config.yml");
            if (!configFile.exists()) {
                Files.copy(
                        getResourceAsStream("config.yml"),
                        configFile.toPath(),
                        StandardCopyOption.REPLACE_EXISTING
                );
            }
            BallBungeeCordAPI.init(configFile);
            logger.info("已初始化 BallAPI");
        } catch (Exception e) {
            logger.log(Level.SEVERE, "BallAPI 初始化失败", e);
            ProxyServer.getInstance().stop("由于 HamsterBall 初始化失败, 服务器将立即关闭");
            return;
        }
        long time = System.currentTimeMillis() - start;
        logger.info("仓鼠球初始化完成，总计耗时 " + time + " ms");
    }

    @Override
    public void onEnable() {
        long start = System.currentTimeMillis();
        Logger logger = getLogger();
        logger.info("仓鼠球正在启动");
        try {
            BallBungeeCordAPI.getInstance().enable();
        } catch (Exception e) {
            logger.log(Level.SEVERE, "仓鼠球启动失败", e);
            logger.info("由于仓鼠球启动失败，服务器将立即关闭");
            ProxyServer.getInstance().stop("仓鼠球启动失败");
            return;
        }
        BallAPI.getInstance().getEventBus().register(BallBungeeListener.INSTANCE);
        logger.info("已注册监听器 BallBungeeListener");
        ProxyServer.getInstance().getPluginManager().registerListener(this, BallBungeeMainListener.INSTANCE);
        logger.info("已注册监听器 BallBungeeMainListener");
        ProxyServer.getInstance().getPluginManager().registerListener(this, UpdatePlayerInfoListener.INSTANCE);
        logger.info("已注册监听器 UpdatePlayerInfoListener");

        if (BallAPI.getInstance().getBallConfig().isGameServerUpdatePlayerInfo()) {
            BallAPI.getInstance().subscribePatterns("*" + BallAPI.PLAYER_INFO_CHANNEL);
        } else {
            BallAPI.getInstance().subscribeIgnorePrefix(BallAPI.PLAYER_INFO_CHANNEL);
        }
        BallAPI.getInstance().sendRawBallMessage(
                BallAPI.BALL_CHANNEL, BallActions.ServerOnline.name(),
                new ServerOnlineEvent(BallAPI.getInstance().getLocalServerInfo())
        );
        // 移除失效的在线玩家
        BallAPI.getInstance().getAllPlayerInfo().values()
                .stream()
                .filter(BallPlayerInfo::isOnline)
                .filter(o -> BallAPI.getInstance().isLocalServer(o.getProxyServer()))
                .forEach(playerInfo -> {
                    playerInfo.setOnline(false);
                    BallBungeeCordUtils.uploadPlayerInfo(playerInfo);
                });
        long time = System.currentTimeMillis() - start;
        logger.info("仓鼠球启动完成，总计耗时 " + time + " ms");
    }

    @Override
    public void onDisable() {
        long start = System.currentTimeMillis();
        Logger logger = getLogger();
        logger.info("仓鼠球正在关闭");
        try {
            BallBungeeCordAPI.getInstance().disable();
        } catch (Exception e) {
            logger.log(Level.SEVERE, "关闭仓鼠球时遇到了一个异常", e);
        }
        long time = System.currentTimeMillis() - start;
        logger.info("仓鼠球已关闭，总计耗时 " + time + " ms");
    }
}
